package com.tonggedata.dataapi.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.apache.dolphinscheduler.api.utils.PageInfo;

import org.springframework.stereotype.Service;
import cn.hutool.core.bean.BeanUtil;

import com.tonggedata.dataapi.entity.ApiBizConsumer;
import com.tonggedata.dataapi.service.ApiBizConsumerService;
import com.tonggedata.dataapi.mapper.ApiBizConsumerMapper;
import com.tonggedata.dataapi.dto.ApiBizConsumerDto;
import com.tonggedata.dataapi.dto.ApiBizConsumerParamDto;
import com.tonggedata.dataapi.util.ApiServiceUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.dao.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.StrUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;

/**
 * ==================================================
 *
 * @author : tonggedata
 * @fileName:
 * @create : 2022-06-19 13:08:47
 * @Description： api业务应用名称，网关consumer
 * ==================================================
 * @since 1.0.0
 */
@Service
public class ApiBizConsumerServiceImpl extends ServiceImpl<ApiBizConsumerMapper, ApiBizConsumer> implements ApiBizConsumerService {


    private static final Logger logger = LoggerFactory.getLogger(ApiBizConsumerServiceImpl.class);

    @Autowired
    private ApiBizConsumerMapper apiBizConsumerMapper;

    @Override
    public Map<String, Object> queryApiBizConsumer(long id) {
        Map<String, Object> result = new HashMap<>();
        ApiBizConsumer apiBizConsumer = getById(id);
        if (apiBizConsumer == null) {
//            putMsg(result, Status.RESOURCE_NOT_EXIST);
            return result;
        }
        // type
        ApiBizConsumerDto apiBizConsumerDto = new ApiBizConsumerDto();
        BeanUtil.copyProperties(apiBizConsumer, apiBizConsumerDto);

        result.put(Constants.DATA_LIST, apiBizConsumerDto);
        ApiServiceUtil.putMsg(result, Status.SUCCESS);
        return result;
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<Object> delete(User loginUser, long id) {
        Result<Object> result = new Result<>();
        try {
            //query datasource by id
            ApiBizConsumer apiBizConsumer = getById(id);
            if (apiBizConsumer == null) {
                logger.error("resource id {} not exist" , id);
                ApiServiceUtil.putMsg(result, Status.RESOURCE_NOT_EXIST);
                return result;
            }
            if (!ApiServiceUtil.hasPerm(loginUser, apiBizConsumer.getCreateUser())) {
                ApiServiceUtil.putMsg(result, Status.USER_NO_OPERATION_PERM);
                return result;
            }
            apiBizConsumerMapper.deleteById(id);
            ApiServiceUtil.putMsg(result, Status.SUCCESS);
        } catch (Exception e) {
            logger.error("delete apiBizConsumer error" , e);
            throw new RuntimeException("delete apiBizConsumer error" );
        }
        return result;
    }

    @Override
    public Result queryApiBizConsumerListPaging(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
        Result result = new Result();
        Page<ApiBizConsumer> apiBizConsumerPage = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<ApiBizConsumer> lambdaQuery = new LambdaQueryWrapper<ApiBizConsumer>();
        if (!ApiServiceUtil.isAdmin(loginUser)) {
            lambdaQuery.eq(ApiBizConsumer::getCreateUser, loginUser.getUserName());
        }
        if (StrUtil.isNotEmpty(searchVal)) {
            //lambdaQuery.eq(ApiBizConsumer::getName, searchVal);
        }
        IPage<ApiBizConsumer> ipage = page(apiBizConsumerPage, lambdaQuery);
        //转换格式
        PageInfo<ApiBizConsumer> pageInfo = new PageInfo<>(pageNo, pageSize);
        pageInfo.setTotal((int) ipage.getTotal());
        pageInfo.setTotalList(ipage.getRecords());
        result.setData(pageInfo);
        ApiServiceUtil.putMsg(result, Status.SUCCESS);
        return result;
    }

    @Override
    public Map<String, Object> queryApiBizConsumerList(User loginUser, String name) {
        Map<String, Object> result = new HashMap<>();

        LambdaQueryWrapper<ApiBizConsumer> lambdaQuery = new LambdaQueryWrapper<ApiBizConsumer>();

        if (!ApiServiceUtil.isAdmin(loginUser)) {
            lambdaQuery.eq(ApiBizConsumer::getCreateUser, loginUser.getUserName());
        }
        if (StrUtil.isNotEmpty(name)) {
            lambdaQuery.like(ApiBizConsumer::getName, name);
        }
        List<ApiBizConsumer> apiBizConsumerList = apiBizConsumerMapper.selectList(lambdaQuery);

        result.put(Constants.DATA_LIST, apiBizConsumerList);
        ApiServiceUtil.putMsg(result, Status.SUCCESS);

        return result;
    }


    @Override
    public Result<Object> updateApiBizConsumer(long id, User loginUser, ApiBizConsumerParamDto apiBizConsumerParam) {
        //ApiBizConsumerUtil.checkApiBizConsumerParam(apiBizConsumerParam);
        Result<Object> result = new Result<>();
        ApiBizConsumer apiBizConsumer = getById(id);
        if (apiBizConsumer == null) {
            // putMsg(result, Status.RESOURCE_NOT_EXIST);
            return result;
        }

        if (!ApiServiceUtil.hasPerm(loginUser, apiBizConsumer.getCreateUser())) {
            ApiServiceUtil.putMsg(result, Status.USER_NO_OPERATION_PERM);
            return result;
        }

        //check name can use or not
        if (!apiBizConsumer.getName().trim().equals(apiBizConsumer.getName()) && checkName(apiBizConsumer.getName())) {
            //putMsg(result, Status.DATASOURCE_EXIST);
            return result;
        }

        BeanUtil.copyProperties(apiBizConsumerParam, apiBizConsumer, CopyOptions.create().setIgnoreNullValue(true));
        try {
            apiBizConsumer.setUpdateTime(new Date());
            apiBizConsumer.setUpdateUser(loginUser.getUserName());
            apiBizConsumerMapper.updateById(apiBizConsumer);
            ApiServiceUtil.putMsg(result, Status.SUCCESS);
        } catch (DuplicateKeyException ex) {
            logger.error("Update apiBizConsumer error." , ex);
            ApiServiceUtil.putMsg(result, Status.DATASOURCE_EXIST);
        }
        return result;
    }

    private boolean checkName(String name) {
        LambdaQueryWrapper<ApiBizConsumer> lambdaQuery = new LambdaQueryWrapper<ApiBizConsumer>();
        lambdaQuery.eq(ApiBizConsumer::getName, name);
        List<ApiBizConsumer> apiBizConsumerList = apiBizConsumerMapper.selectList(lambdaQuery);
        return apiBizConsumerList != null && !apiBizConsumerList.isEmpty();
    }

    @Override
    public Result<Object> createApiBizConsumer(User loginUser, ApiBizConsumerParamDto apiBizConsumerParam) {
        //DatasourceUtil.checkApiBizConsumerParam(apiBizConsumerParam);
        Result<Object> result = new Result<>();
        // check name can use or not
      /* if (checkName(apiBizConsumerParam.getName())) {
            putMsg(result, Status.DATA_API_GROUP_ERROR);
            return result;
        }*/

        // build apiBizConsumer
        ApiBizConsumer apiBizConsumer = new ApiBizConsumer();
        Date now = new Date();


        //apiBizConsumer.setCreateUser(loginUser.getUserName());
        BeanUtil.copyProperties(apiBizConsumerParam, apiBizConsumer, CopyOptions.create().setIgnoreNullValue(true));

        //apiBizConsumer.setCreateTime(now);
        apiBizConsumer.setUpdateTime(now);
        try {
            apiBizConsumerMapper.insert(apiBizConsumer);
            ApiServiceUtil.putMsg(result, Status.SUCCESS);
        } catch (DuplicateKeyException ex) {
            logger.error("Create apiBizConsumer error." , ex);
            ApiServiceUtil.putMsg(result, Status.DATA_API_GROUP_ERROR);
        }

        return result;
    }

}
